/* 
1 页面加载完毕之后 发送请求 获取数据 和 渲染页面
    1 componentDidMount 来发送异步请求 
    2 一开始需要的接口的参数只有3个  (城市id,从第几条数据开始,到第几条数据结束)
    3 为了方便管理以上的接口参数 需要将它们 定义成全局对象 

2 需要将 原生的页面滚动 改成 虚拟列表 

3 分页加载 
  1 先触发 分页事件 滚动条触底事件 ->   onReachBottom  (通过onscroll的三个高度来构造分页事件)

  2 解决一开始的 Onscroll事件的触发 
    this.state.list.length === 0 通过有没有数组来判断是否是第一次加载 

  3 分页业务
    1 一定有下一页数据 ??? 
      先判断有没有下一页数据  count 总条数 手上是不是有 开始的条数 
      当前的开始的条数 和 总条数做个比较即可 
    2 假设 有下一页数据
      1 对start开始的条数 += 20  => 21 , 对end结束的条数   +=20   =>40
      2 直接发送请求即可 
      3 数据请求回来 state的数组 要的是 追加数据 而不是 直接替换
    3 节流阀!! 
      1 上一次的请求没有结束 那么就不能够 开启下一次请求 
      2 前面没有人发送请求 我们现在就开始发送请求  
        this.Loading=true;  // 表示有人正在使用 
      3 请求完毕 
        this.Loading=false; // 表示 请求已经回来  下一个人就可以使用 发送请求了 
      



4 数据筛选 渲染 
  1 无法就是一个对象合并 
  2 为了方便使用  定义一个全局变量 接收筛选组件的 筛选数据 
  3 当用户点击 了 筛选的按钮之后
    0 先重置
      1 清空旧数组 
      2 重置 开始的条数和结束的条数 

    1 将子组件传递过来的筛选数据 赋值个 全局变量 FiltetParams
    2 再发送请求 

5 分页的关键字
  1 分页事件如何触发 三个高度
  2 判断还有没有下一页的逻辑 
  3 请求成功后的数组 是追加
  4 节流阀
  5 重置
    1 重置 页面显示的数组
    2 重置页码
    3 重置页面的筛选条件 .... ??

6 出现bug
  1 现象
    1 首次加载页面的时候 数据是正确
    2 点击了城市选择页面 修改了 当前城市的话, 
      页面中的数据 和 城市输入组件中数据对应不上了 
      1 页面中的数据 落后一次 城市输入组件中的城市信息 
  2 原因
    1 componentDidMount 城市名称 和 城市输入组件中的城市 对应不上
      1 为什么对应不上呢 ?? (生命周期 -  异步redux的理解)

    2  出现不过的步骤
      1 首次打开页面的时候 正常   redux中的城市名称 "广州"
      2 点击 城市选择页面
      3 在 "城市选择页面" 中 选择了一个其他城市 
      4 同时 触发一个异步acion 假设需要花费 1分钟的时间去加载数据
      4 同时 返回上个页面
        1 页面马上就触发了 页面的挂载 事件 (这个时候 刚才的异步请求还没有回来-城市还是旧"广州")
        2 直接拿 旧的城市 "广州" 做一系列的 功能 
        3 页面把 "广州" 相关的数据都显示出来了
      5 第四个步骤中的异步请求 回来了 
        把 城市输入组件中的 城市名称 改为 被点击的 新的城市名称
      6 综上所述: 导致了 页面数据 和 城市输入组件中的数据对应不上!! 
    
  3 解决:
    1 redux数据更新后再触发页面返回 对redux 有更加深刻的理解 
      1 当数据更新完毕了  才返回上一页 
      2 vuex中的异步action的返回值 也可以是一个promise 
        1 点击一个按钮 按顺序运行多个 异步action的 复杂操作 
      3 需要在 actionCreator中 对 异步acion的返回的函数 里面再做一个return  
        1  return  getPoint(cityName)
        2 return dispatch(actionUpateCity(cityName)); 
  
    2 设置个全局的开关  在 根组件中做个判断了 
      1 在城市选择页面中 点击了城市名称的时候 多做一个步骤 
        1 将 redux中的城市数据清空 
        2 那么根组件中的 App的判断会生效-> 不会显示任何页面
        3 同时 异步action也触发了 
        4 数据回来后 拿到了最新的城市信息
        5 app中的判断有生效
        6 最终  列表找房页面的 组件挂载完毕事件中的 当前城市 就是最新的了 
    3 生命周期更新可以检测到吗    搞不定!!! 
    4 强制刷新一遍   搞不定!!!  react 单页面应用程序 路由 不刷新 
    5 能监听到redux数据更新吗  监听到后再触发 
      1 能监听 !! 
      2 不能做到 再触发 
    6 更新生命周期  componentUpdate  搞不定!!! 
      内部中 不能去修改 state 或者 props的 否则的话 死循环 
 */


import React, { Component } from 'react';
import { NavBar, Icon } from 'antd-mobile';
import CityInput from "../../components/CityInput";
import Css from "./index.module.scss";
import Filter from "./Filter";
import { connect } from "react-redux";
import { request } from "../../utils/request";
import HouseItem from "../../components/HouseItem";

import { List } from "react-virtualized";

console.log("列表找房");
class Found extends Component {

  // 一开始需要发送到后台的接口参数
  Params = {
    // 城市id -1 默认值 需要修改
    cityId: -1,
    // 开始的条数
    start: 1,
    // 结束的条数
    end: 20
  }

  // 用来接收 筛选组件 传递过来的筛选对象
  FiltetParams = {}

  // 总条数
  TotalCount = 1;

  // 节流阀
  IsLoading = false;

  state = {
    // 房源列表
    list: []
  }

  async componentDidMount() {
    const cityName = this.props.cityName;
    const id = (await request.get("/area/info?name=" + cityName)).data.body.value;
    this.Params.cityId = id;
    // 发送请求获取房源列表数据
    this.getList();
  }

  // 获取页面的数据
  getList = async () => {
    // axios 支持 接收一个对象形式的参数 => 转成 /houses?cityId=1&start=2
    // const res = await request.get("/houses", { params: this.Params });
    const res = await request.get("/houses", { params: { ... this.Params, ...this.FiltetParams } });
    // 获取数据的总条数
    this.TotalCount = res.data.body.count;
    // 分页-追加数据
    this.setState({ list: [...this.state.list, ...res.data.body.list] });

    // 请求已经发送完毕了
    this.IsLoading = false;
  }

  // 接收筛选组件的值
  onHandleSubmit = (filterParams) => {
    // 1 清空旧数组
    this.setState({ list: [] });
    this.Params.start=1;
    this.Params.end=20;

    this.FiltetParams=filterParams;
    this.getList();
  }
  // 行渲染函数
  rowRenderer = ({
    key, // Unique key within array of rows
    index, // Index of row within collection
    style, // Style object to be applied to row (to position it)
  }) => {
    return (
      <div key={key} style={style}>
        <HouseItem houseItem={this.state.list[index]} />
      </div>
    );
  }

  // 列表的滚动事件
  // List 有内容了之后 会先自己触发一次  onScroll
  onScroll = ({ clientHeight, scrollHeight, scrollTop }) => {

    // 1 是否页面一开始的时候 出发的onScroll
    const isFirst = this.state.list.length === 0;
    // 2 是否是滚动条触底了
    const isReachBottom = scrollHeight - clientHeight - scrollTop < 15;
    // 3 还有没有下一页数据 
    const hasMore = this.Params.start < this.TotalCount;

    // 主要是找不合法  
    if (isFirst || !isReachBottom || !hasMore || this.IsLoading) {
      return;
    }

    this.IsLoading = true;
    console.log("满足了所有的合法条件 可以 加载下一页啦");
    this.Params.start += 20;
    this.Params.end += 20;
    this.getList();


    // console.clear();
    // clientHeight  滚动容器的高度
    // scrollHeight   被滚动的长列表的高度
    // scrollTop  页面滚动了的高度 (页面被卷去高度  滚动条距离顶部的高度)
    // console.log("clientHeight", clientHeight);
    // console.log("scrollHeight", scrollHeight);
    // console.log("scrollTop", scrollTop);

    // 拿最高的 高度 减去其他的高度即可
    // console.log("滚动条距离底部的高度",scrollHeight-clientHeight-scrollTop);

  }
  render() {
    return (
      <div className={Css.found} >
        {/* 1.0 导航栏 开始 */}
        <div className={Css.found_nav}>
          <NavBar
            style={{ backgroundColor: "#f6f5f6" }}
            mode="light"
            icon={<Icon type="left" />}
            onLeftClick={() => this.props.history.goBack()}
          >列表找房</NavBar>
          <div className={Css.city_input}>
            <CityInput iconColor="#21b97a" />
          </div>
        </div>
        {/* 1.0 导航栏 结束 */}

        {/* 2.0 筛选组件 开始 */}
        <div className={Css.found_filter}>
          <Filter onHandleSubmit={this.onHandleSubmit} />
        </div>
        {/* 2.0 筛选组件 结束 */}

        {/* 3.0 列表内容 开始 */}
        <div className={Css.house_list}>
          <List
            width={window.screen.width}
            height={window.screen.height - 130}
            rowCount={this.state.list.length}
            rowHeight={120}
            rowRenderer={this.rowRenderer}
            onScroll={this.onScroll}
          />
        </div>
        {/* 3.0 列表内容 结束 */}
      </div>
    );
  }
}


const mapStateToProps = (state) => {
  // 修改了 props => render shouldComponentUpdate(判断和处理来决定是否更新)  componentUpdate
  // 又触发了 state 的改变  死循环了!! 
  return { cityName: state.mapReducer.city.name }
};



export default connect(mapStateToProps)(Found);